package com.gs.cd.cloud.start.exception;

import cn.hutool.core.util.StrUtil;
import com.gs.cd.api.ApiResult;
import com.netflix.config.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.time.format.DateTimeParseException;
import java.util.Objects;

/**
 * create by hippo  2020/2/13
 *
 * @Description
 **/
@Slf4j
@RestControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE - 2) //值越小，越先执行
public class DefaultGlobalExceptionHandler {

    /**
     * SpringMvc @valid @Validated 校验
     * todo ValidationException 的值
     */
    @ExceptionHandler(ValidationException.class)
    public ApiResult validationException(ValidationException exception) {
        exception.printStackTrace();
        return ApiResult.error(getFrontMsg(exception, true));
    }


    /**
     * 其他异常情况处理
     */
    @ExceptionHandler(value = {Exception.class})
    public ApiResult handleAllException(Exception ex) {
        ex.printStackTrace();
        return ApiResult.error("其他异常：错误咯！");
    }

    /**
     * 不符合业务逻辑要求
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public ApiResult badRequestException(IllegalArgumentException exception) {
        exception.printStackTrace();
        return ApiResult.error("非法数据！");
    }

    /**
     * SpringMvc校验bean失败
     */
    @ExceptionHandler
    public ApiResult badRequestException(MethodArgumentNotValidException exception) {
        exception.printStackTrace();
        return ApiResult.error(exception.getBindingResult().getFieldError() == null ? "SpringMvc校验bean失败"
                : exception.getBindingResult().getFieldError().getDefaultMessage());
    }


    @ExceptionHandler
    public ApiResult badRequestException(DateTimeParseException exception) {
        exception.printStackTrace();
        return ApiResult.error(HttpStatus.BAD_REQUEST.getReasonPhrase());
    }

    @ExceptionHandler
    public ApiResult badRequestException(ClassCastException exception) {
        exception.printStackTrace();
        return ApiResult.error("类型转换错误");
    }

    @ExceptionHandler
    public ApiResult badRequestException(HttpMessageNotReadableException exception) {
        exception.printStackTrace();
        return ApiResult.error("传入数值不符合要求,无法转化为对应的值，请检查属性格式，尤其是time的格式");
    }

//    @ExceptionHandler
//    public ApiResult nullInputException(NullInputException exception) {
//        exception.printStackTrace();
//        return ApiResult.error("要求必需的传入参数不能为空值");
//    }

    @ExceptionHandler
    public ApiResult nullInputException(NullPointerException exception) {
        exception.printStackTrace();
        return ApiResult.error("程序内部空指针异常，请联系程序员");
    }

    /***还需完成其他异常***/


    private String getFrontMsg(Exception exception, boolean printLog) {
        String exceptionMsg = exception.getMessage();

        if (printLog) {
            log.error(ExceptionUtils.getStackTrace(exception));
        } else {
            log.debug(ExceptionUtils.getStackTrace(exception));
        }
        if (StrUtil.isBlank(exceptionMsg)) {
            return "";
        }

        if (exceptionMsg.contains(":")) {
            return exceptionMsg.split(":")[1];
        } else return exceptionMsg;
    }
}
